﻿//using System.Collections.Generic;
//using OneWorks.Metadata.Entity;

//namespace OneWorks.Repositories
//{
//    using System;
//    using System.Linq.Expressions;

//    using Metadata.Interface;
//    using Interface;
//    using Utils.Specifications;

//    /// <summary>
//    /// Represents the base class for repositories.
//    /// </summary>
//    /// <typeparam name="TAggregateRoot">The type of the aggregate root on which the repository operations
//    /// should be performed.</typeparam>
//    public abstract class Repository<TAggregateRoot> : IRepository<TAggregateRoot>
//        where TAggregateRoot : class, IAggregateRoot
//    {
//        #region Private Fields

//        private readonly IRepositoryContext _context;

//        #endregion

//        #region Ctor
//        /// <summary>
//        /// Initializes a new instance of <c>Repository&lt;TAggregateRoot&gt;</c> class.
//        /// </summary>
//        /// <param name="context">The repository context being used by the repository.</param>
//        protected Repository(IRepositoryContext context)
//        {
//            _context = context;
//        }
//        #endregion

//        #region Protected Methods

//        /// <summary>
//        /// Adds an aggregate root to the repository.
//        /// </summary>
//        /// <param name="aggregateRoot">The aggregate root to be added to the repository.</param>
//        protected abstract void DoAdd(TAggregateRoot aggregateRoot);

//        /// <summary>
//        /// Gets the aggregate root instance from repository by a given key.
//        /// </summary>
//        /// <param name="key">The key of the aggregate root.</param>
//        /// <returns>The instance of the aggregate root.</returns>
//        protected abstract TAggregateRoot DoGetByKey(Guid key);

//        /// <summary>
//        /// 
//        /// </summary>
//        /// <param name="specification"></param>
//        /// <returns></returns>
//        protected abstract TAggregateRoot DoGet(ISpecification<TAggregateRoot> specification);

//        /// <summary>
//        /// Checkes whether the aggregate root, which matches the given specification, exists in the repository.
//        /// </summary>
//        /// <param name="specification">The specification with which the aggregate root should match.</param>
//        /// <returns>True if the aggregate root exists, otherwise false.</returns>
//        protected abstract bool DoExists(ISpecification<TAggregateRoot> specification);

//        /// <summary>
//        /// Removes the aggregate root from current repository.
//        /// </summary>
//        /// <param name="aggregateRoot">The aggregate root to be removed.</param>
//        protected abstract void DoRemove(TAggregateRoot aggregateRoot);

//        /// <summary>
//        /// Updates the aggregate root in the current repository.
//        /// </summary>
//        /// <param name="aggregateRoot">The aggregate root to be updated.</param>
//        protected abstract void DoUpdate(TAggregateRoot aggregateRoot);

//        protected abstract TAggregateRoot DoFind(ISpecification<TAggregateRoot> specification);

//        protected abstract PagedResult<TAggregateRoot> DoFind(ISpecification<TAggregateRoot> specification, FindPage page);

//        /// <summary>
//        /// 
//        /// </summary>
//        /// <typeparam name="TKey"></typeparam>
//        /// <param name="specification"></param>
//        /// <param name="expression"></param>
//        /// <param name="value"></param>
//        protected abstract void DoUpdate<TKey>(Guid specification, Expression<Func<TAggregateRoot, TKey>> expression, object value);
        
//        #endregion

//        #region IRepository<TAggregateRoot> Members
//        /// <summary>
//        /// Gets the <see cref="IRepositoryContext"/> instance.
//        /// </summary>
//        public IRepositoryContext Context
//        {
//            get { return _context; }
//        }

//        /// <summary>
//        /// Adds an aggregate root to the repository.
//        /// </summary>
//        /// <param name="aggregateRoot">The aggregate root to be added to the repository.</param>
//        public void Add(TAggregateRoot aggregateRoot)
//        {
//            DoAdd(aggregateRoot);
//        }

//        /// <summary>
//        /// Gets the aggregate root instance from repository by a given key.
//        /// </summary>
//        /// <param name="key">The key of the aggregate root.</param>
//        /// <returns>The instance of the aggregate root.</returns>
//        public TAggregateRoot GetByKey(Guid key)
//        {
//            return DoGetByKey(key);
//        }
 
//        /// <summary>
//        /// Removes the aggregate root from current repository.
//        /// </summary>
//        /// <param name="aggregateRoot">The aggregate root to be removed.</param>
//        public void Remove(TAggregateRoot aggregateRoot)
//        {
//            DoRemove(aggregateRoot);
//        }

//        /// <summary>
//        /// Updates the aggregate root in the current repository.
//        /// </summary>
//        /// <param name="aggregateRoot">The aggregate root to be updated.</param>
//        public void Update(TAggregateRoot aggregateRoot)
//        {
//            DoUpdate(aggregateRoot);
//        }

//        public void Update<TKey>(Guid guid, Expression<Func<TAggregateRoot, TKey>> expression, object value)
//        {
//             DoUpdate(guid, expression, value);
//        }

//        public TAggregateRoot Find(ISpecification<TAggregateRoot> specification)
//        {
//            return DoFind(specification);
//        }

//        public PagedResult<TAggregateRoot> Find(ISpecification<TAggregateRoot> specification, FindPage page)
//        {
//            return DoFind(specification, page);
//        }

//        /// <summary>
//        /// Gets a single aggregate root instance from repository by using the given specification.
//        /// </summary>
//        /// <param name="specification">The specification with which the aggregate root should match.</param>
//        /// <returns>The aggregate root instance.</returns>
//        public TAggregateRoot Get(ISpecification<TAggregateRoot> specification)
//        {
//            return DoGet(specification);
//        }

//        /// <summary>
//        /// Checkes whether the aggregate root, which matches the given specification, exists in the repository.
//        /// </summary>
//        /// <param name="specification">The specification with which the aggregate root should match.</param>
//        /// <returns>True if the aggregate root exists, otherwise false.</returns>
//        public bool Exists(ISpecification<TAggregateRoot> specification)
//        {
//            return DoExists(specification);
//        }
        
//        #endregion
//    }
//}
